package red.mlz.module.module.game.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import red.mlz.module.module.category.mapper.CategoryMapper;
import red.mlz.module.module.game.dto.GameDetailDto;
import red.mlz.module.module.game.es.GameEs;
import red.mlz.module.module.game.es.GameEsRepository;
import red.mlz.module.module.game.mapper.GameMapper;
import red.mlz.module.module.gametagrelation.mapper.GameTagRelationMapper;
import red.mlz.module.module.tag.mapper.TagMapper;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class GameDataSyncService {

    private final CategoryMapper categoryMapper;
    private final GameMapper gameMapper;
    private final TagMapper tagMapper;
    private final GameTagRelationMapper gameTagRelationMapper;
    private final GameEsRepository gameEsRepository;

    /**
     * 全量同步：将数据库中所有游戏数据同步到ES
     * 适用场景：首次启动、数据初始化、定期全量更新
     */
    @Transactional
    public void fullSyncToEs() {
        log.info("开始全量同步游戏数据到ES...");

        // 1. 查询所有游戏的基础信息（只查ID，避免一次性加载过多数据）
        List<Long> allGameIds = gameMapper.selectAllGameIds();
        if (allGameIds.isEmpty()) {
            log.info("数据库中没有游戏数据，同步结束");
            return;
        }

        // 2. 逐个查询游戏详情（含关联表数据）并同步
        int successCount = 0;
        int failCount = 0;
        for (Long gameId : allGameIds) {
            try {
                //3.聚合多表数据
                GameEs gameEs = buildGameEs(gameId);
                if (gameEs != null) {
                    gameEsRepository.save(gameEs);
                    successCount++;

                    if (successCount % 100 == 0) {
                        log.info("已同步 {} 条记录", successCount);
                    }
                } else {
                    log.warn("游戏ID: {} 构建ES文档失败，可能已被删除", gameId);
                    // 如果游戏已删除，从ES中移除
                    gameEsRepository.deleteById(gameId);
                }
            }catch (Exception e){
                failCount++;
                log.error("同步游戏ID: {} 失败: {}", gameId, e.getMessage());
                // 记录详细异常信息，但继续处理其他记录
                log.debug("详细异常信息:", e);
            }
        }
        log.info("全量同步完成，成功同步{}条，共{}条", successCount, allGameIds.size());
    }

    @Transactional
    public void syncByGameId(Long gameId) {
        if (gameId == null) {
            log.warn("游戏ID为空，同步失败");
            return;
        }

        try {
            GameEs document = buildGameEs(gameId);
            if (document != null) {
                gameEsRepository.save(document);
                log.info("增量同步游戏ID: {} 成功", gameId);
            } else {
                // 如果游戏已删除，从ES中移除
                gameEsRepository.deleteById(gameId);
                log.info("游戏ID: {} 已删除，从ES中移除", gameId);
            }
        } catch (Exception e) {
            log.error("增量同步游戏ID: {} 失败", gameId, e);
        }
    }

    //聚合多表数据，构建ES文档
    private GameEs buildGameEs(Long gameId) {
        //1.查询游戏基础信息
        GameDetailDto game = gameMapper.selectIdWithDetail(gameId);
        if (game == null) {
            return null;
        }

        //2.查询类目名称（通过categoryId查询）
        String categoryName = categoryMapper.getNameByParentId(game.getCategoryId()).toString();

        //3.查询标签列表
        List<Long> tagIds = gameTagRelationMapper.selectTagIdsByGameId(gameId);
        List<String> tagNames = tagIds.stream()
                .map(tagMapper::selectNameById)
                .collect(Collectors.toList());

        //4.构建ES文档
        GameEs gameEs = new GameEs();
        gameEs.setId(gameId);
        gameEs.setGameName(game.getGameName());
        gameEs.setCategoryName(categoryName);
        gameEs.setTagNames(tagNames);
        gameEs.setCategoryId(game.getCategoryId());
        gameEs.setPlayerNumber(game.getPlayNumber());
        gameEs.setCoverImages(game.getCoverImages());

        return gameEs;
    }

}
